package org.example.day08;


import java.util.ArrayList;
import java.util.List;

/**
 * 第三章节3.1.18: 等待条件发生变化
 */
public class MyThread5 {
    private String lock;

    public MyThread5(String lock) {
        this.lock = lock;
    }

    public void add() {
        synchronized (lock) {
            ValueObject.list.add("anyString");
            lock.notifyAll();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        String lock = new String("");
        MyThread5 m5 = new MyThread5(lock);
        Subtract subtract = new Subtract(lock);

        Thread5B tb = new Thread5B(subtract);
        tb.setName("subtractThread");
        tb.start();

        Thread5B tb2 = new Thread5B(subtract);
        tb2.setName("subtractThread2");
        tb2.start();

        Thread.sleep(1000);

        Thread5A ta = new Thread5A(m5);
        ta.setName("addThread");
        ta.start();
    }
}

class ValueObject {
    public static List list = new ArrayList<>();
}

class Subtract{
    private String lock;

    public Subtract(String lock) {
        this.lock = lock;
    }
    public void subtract(){
        try {
            synchronized (lock){
                //if判断会出现异常，while条件不会。
//                if(ValueObject.list.size() == 0){
//                    System.out.println("wait begin ThreadName = " + Thread.currentThread().getName());
//                    lock.wait(); //释放锁
//                    System.out.println("wait end ThreadName = " + Thread.currentThread().getName());
//                }
                while(ValueObject.list.size() == 0){
                    System.out.println("wait begin ThreadName = " + Thread.currentThread().getName());
                    lock.wait(); //释放锁
                    System.out.println("wait end ThreadName = " + Thread.currentThread().getName());
                }
                ValueObject.list.remove(0);
                System.out.println("list size = " + ValueObject.list.size());
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

class Thread5A extends Thread{
    private MyThread5 m5;

    public Thread5A(MyThread5 m5) {
        this.m5 = m5;
    }

    @Override
    public void run() {
        m5.add();
    }
}

class Thread5B extends Thread{
    private Subtract r;

    public Thread5B(Subtract r) {
        this.r = r;
    }

    @Override
    public void run() {
        r.subtract();
    }
}